﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Text;
using fastJSON;
namespace JWTMiddre.Middleware
{
    public class AuthorizationHandler
    {
        private string sacreatekey = "^ *&(phdsajdfljpow2123";
        
        /// <summary>
        ///过期时间分钟
        /// </summary>
        private int ovetime = 30;

        public string GenerateTokenCredential(string usermsg)
        {
            string result = null;
            var payload =usermsg;
            if (payload != null && !payload.Equals("null"))
            {
                var dtNow = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                var jwtHeader =JSON.ToJSON(new JWTSecureDataHeader() { TimeStamp = dtNow });
                var base64Payload = ConverBase64String(payload);
                var encodedString = $"{ConverBase64String(jwtHeader)}.{base64Payload}";
                var signature = HMACSHA256(encodedString, dtNow+sacreatekey+ dtNow);
                result = $"{encodedString}.{signature}";
            }
            return result;
        }
        public bool ValidateClientAuthentication(string token)
        {
            bool isSuccess = false;
            var jwtToken = token.Split('.');
            //token 格式
            if (jwtToken.Length != 3)
            {
                return isSuccess;
            }
            //获取jwtheader信息
            var jwtHeader =fastJSON.JSON.ToObject<JWTSecureDataHeader>(Base64Decode(jwtToken[0]));
            //超时
            if ((DateTime.Parse(jwtHeader.TimeStamp) - DateTime.Now).TotalMinutes> ovetime)
            {
                return isSuccess;
            }
            //签名不正确
            if(jwtToken[2]!= HMACSHA256(jwtToken[0] + "." + jwtToken[1], jwtHeader.TimeStamp + sacreatekey + jwtHeader.TimeStamp))
            {
                return isSuccess;
            }

            isSuccess = true;
            return isSuccess;
        }
        private string ConverBase64String(string str)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
        }

        private string Base64Decode(string Message)
        {
            byte[] bytes = Convert.FromBase64String(Message);
            return Encoding.Default.GetString(bytes);
        }
        private string HMACSHA256(string message, string secret)
        {
            secret = secret ?? "";
            byte[] keyByte = Encoding.UTF8.GetBytes(secret);
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                return Convert.ToBase64String(hashmessage);
            }
        }


        public class JWTSecureDataHeader
        {
            public JWTSecureDataType Type { get; set; }

            public EncryptMode EncryptMode { get; set; }

            public string TimeStamp { get; set; }
        }

        public enum JWTSecureDataType
        {
            JWT
        }
        public enum EncryptMode
        {
            HS256
        }
    }
}
